use super::*;

#[derive(Clone, Copy)]
pub struct Table<'a> {
	pub version: u32, // uint32 version    Version number of the metadata table — set to 1.
	pub flags: u32,   // uint32 flags      Flags — currently unused; set to 0.
	// uint32 (reserved) Not used; set to 0. - OpenType
	// Offset from the beginning of the table to the data - TrueType
	pub data_offset: u32,
	// uint32	dataMapsCount	The number of data maps in the table.
	// DataMap	dataMaps[dataMapsCount]	Array of data map records.
	pub data_maps: LazyArray32<'a, DataMapRecord>,

	pub data: &'a [u8],
}
impl<'a> Table<'a> {
	pub const TAG_APPL: Tag = Tag::from_bytes(b"appl");
	pub const TAG_BILD: Tag = Tag::from_bytes(b"bild");
	pub const TAG_DLNG: Tag = Tag::from_bytes(b"dlng");
	pub const TAG_SLNG: Tag = Tag::from_bytes(b"slng");
	pub fn parse(data: &'a [u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		Some(Self {
			version: s.read()?,
			flags: s.read()?,
			data_offset: s.read()?,
			data_maps: s.parse_array32()?,
			data,
		})
	}
	pub fn get(&self, index: u32) -> Option<DataMap<'a>> {
		self.get_(self.data_maps.get(index)?)
	}
	pub fn get_(&self, r: DataMapRecord) -> Option<DataMap<'a>> {
		DataMap::new(r, self.data)
	}
}
impl<'a> core::fmt::Debug for Table<'a> {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		f.debug_struct("Table")
			.field("version", &self.version)
			.field("flags", &self.flags)
			.field("data_offset", &self.data_offset)
			.field("data_maps", &self.data_maps)
			// .field("data", &self.data)
			.finish()
	}
}

#[derive(Debug, Clone, Copy)]
pub struct DataMapRecord {
	// Tag	tag	A tag indicating the type of metadata.
	pub tag: Tag,
	// Offset32	dataOffset	Offset in bytes from the beginning of the metadata table to the data for this tag.
	pub data_offset: Offset32,
	// uint32	dataLength	Length of the data, in bytes. The data is not required to be padded to any byte boundary.
	pub data_length: u32,
}
impl FromData for DataMapRecord {
	const SIZE: usize = 12;
	fn parse(data: &[u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		Some(Self {
			tag: s.read()?,
			data_offset: s.read()?,
			data_length: s.read()?,
		})
	}
}
#[derive(Debug, Clone, Copy)]
pub struct DataMap<'a> {
	pub tag: Tag,
	pub data: &'a [u8],
}
impl<'a> DataMap<'a> {
	pub fn new(r: DataMapRecord, data: &'a [u8]) -> Option<Self> {
		let start = r.data_offset.to_usize();
		let end = start + r.data_length as usize;
		Some(Self {
			tag: r.tag,
			data: data.get(start..end)?,
		})
	}
}
